package com.lance.answer.question_answer;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.lance.answer.dto.CompleteInfo;
import com.lance.answer.gui.answer.AnswerObject;
import com.lance.answer.gui.answer.Util;
import com.lance.answer.util.Constant;
import com.lance.answer.util.HttpClientUtil;
import com.lance.answer.util.MD5Utils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class AnswerTask extends Thread{

    private List<String> urlTasks;
    private Map<String, AnswerObject> answers;
    private String subjectName;
    private String driverPath;
    private LinkedBlockingDeque users;
    private boolean commit;
    private boolean push;

    public AnswerTask(List<String> urlTasks, Map<String, AnswerObject> answers, String subjectName, String driverPath, LinkedBlockingDeque users, boolean commit, boolean push) {
        this.urlTasks = urlTasks;
        this.answers = answers;
        this.subjectName = subjectName;
        this.driverPath = driverPath;
        this.users = users;
        this.commit = commit;
        this.push = push;
    }

    public AnswerTask() {
    }

    // 管理学基础 2065001457555 19940419
    @SneakyThrows
    @Override
    public void run() {

        while (users.size() > 0) {
            String user = Constant.USER_QUEUE.take();
            String[] strs1 = user.split(",");
            String userName = strs1[0];
            String password = strs1[1].substring(6, 14);
            password = "Ouchn" + password;
            Constant.COUNT.getAndAdd(1);
            log.info("{} 正在执行第 {} 位用户，用户名：{} 密码：{}, 进度：{}/{}", Thread.currentThread().getName(), Constant.COUNT.get(), userName, password,Constant.COUNT.get(),Constant.SUM);

            WebDriver driver = Util.getDriver(driverPath);
            //String url = "http://student.ouchn.cn/";
            String url = "http://passport.ouchn.cn/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dstudentspace%26redirect_uri%3Dhttp%253A%252F%252Fstudent.ouchn.cn%252F%2523%252Fsignin-oidc%2523%26response_type%3Did_token%2520token%26scope%3Dopenid%2520profile%2520ouchnuser%2520ouchnstudentspaceapi%2520offline_access%26state%3Dca1cb5d0270b49fdaea508b8a846c457%26nonce%3Dd257df51b0a141ac8ed35b1caf59ef4c";
            driver.get(url);
            Thread.sleep(3000);
            //Util.login(driver, "2065001457555", "19940419");
            Util.login(driver, userName, password);
            Util.switchToFirst(driver);
            Thread.sleep(3000);
            // 形考作业的链接 管理学
            //List<String> urlTasks = Util.getCourseTaskUrl(driver, CourseTypeEnum.BasicManagement.name);
            //List<String> urlTasks = Util.getCourseTaskUrl(subjectCode);

            // 判断是否找到课程
            boolean isFindSubject = false;

            //chromeDriver.navigate().refresh();
            for (WebElement we : driver.findElements(By.className("media-body"))) {
                Util.switchToFirst(driver);
                // 找到管理学基础
                String mediaTitle = we.findElement(By.className("media-title")).getText();

                if (!mediaTitle.contains(subjectName)) {
                    continue;
                }
                isFindSubject = true;
                try {
                    //点击进入学习的按钮
                    WebElement studyButton = we.findElement(By.cssSelector("button[class='btn bg-primary']"));
                    studyButton.click();
                    //Util.switchToLast(driver);
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    File file = new File("d:\\user.txt");
                    FileOutputStream outputStream = new FileOutputStream(file, true);
                    //  String s= "用户："+userName+"毛概视频未刷\r\n";
                    String s = userName + "," + password + "\r\n";
                    outputStream.write(s.getBytes());
                    try {
                        driver.close();
                        driver.quit();
                    } catch (Exception e2) {

                    }
                }
            }

            System.out.println(urlTasks.toString());

            Map<Integer, Double> mmmm = Maps.newHashMap();
            mmmm.put(0, 20.0);
            mmmm.put(1, 20.0);
            mmmm.put(2, 20.0);
            mmmm.put(3, 20.0);
            mmmm.put(4, 20.0);


            int kkk = 0;
            for (String urlTask : urlTasks) {
                // FIXME 当完成第一份形考任务时，必须提交，否则会弹出 ”是否保存当前页面“消息
                driver.get(urlTask);
                // FIXME 延长了
                Thread.sleep(3 * 1000);
                // 点击继续作业

                boolean isGoOn = true;

                // cell c2
                CompleteInfo completeInfo = new CompleteInfo();
                try {
                    List<WebElement> tdList = driver.findElements(By.cssSelector("td[class='cell c2']"));

                    for (WebElement td : tdList) {
                        String score = td.getText();
                        //     System.err.println(score);
                        if ("还未评分".equals(score)) {
                            System.err.println("还未评分");
                            isGoOn = false;
                            break;
                        }
                        double d = Double.parseDouble(score);
                        if (d >= 18.0) {
                            //       if (d >= mmmm.get(kkk)) {
                            completeInfo.setScore(score);
                            System.err.println("成绩已达到80.0分，跳过");
                            isGoOn = false;
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Thread.sleep(2000);
                } finally {
                    kkk++;
                }
                if (!isGoOn) {
                    boolean hasGoOn = false;
                    for (WebElement we : driver.findElements(By.cssSelector("button[class='btn btn-secondary']"))) {
                        if (!Strings.isNullOrEmpty(we.getText()) && "继续上次试答".equals(we.getText().trim())) {
                            hasGoOn = true;
                        }
                    }
                }
                try {
                    Thread.sleep(5000);
                    WebElement doWorkArea = driver.findElement(By.cssSelector("div[class='box py-3 quizattempt']"));
                    doWorkArea.findElement(By.cssSelector("button[class='btn btn-secondary']")).click();
                } catch (Exception e) {
                    try {
                        System.err.println("taskUrl:" + urlTask + "  occur error");
                        e.printStackTrace();
                        driver.close();
                        driver.quit();
                    } catch (Exception e1) {

                    }
                    return;
                }
                Thread.sleep(2 * 1000);
                //回到试题首页
                WebElement element = driver.findElement(By.id("quiznavbutton1"));
                element.click();
                Thread.sleep(2 * 1000);
                // 回到首页
                //Util.goHomePageIndex(driver);
                boolean hashNextPage = true;
                while (hashNextPage) {
                    try {
                        Thread.sleep(4000);
                        // 单个页面的所有题目的集合
                        List<WebElement> singlePageQuestion = Util.getSinglePageQuestionList(driver);
                        // 遍历每个问题|题目


                        for (WebElement singleSubject : singlePageQuestion) {

                            WebElement contentElement = singleSubject.findElement(By.className("content"));

                            String title;
                            title = Util.getTitle(contentElement);
                            //兼容特殊字符
                            title = Util.dealContent(title);

                            String questionCode = MD5Utils.encode(subjectName + title);

                            if (!answers.containsKey(questionCode)) {
                                System.out.println("答案不存在");
                                System.out.println(title);
                                Map<String, String> map = new HashMap<>();
                                map.put("答案不存在", "未能从题库中匹配到");
                                map.put("答案标题", title);
                                map.put("课程名", subjectName);
                                //  Thread.sleep(5000000);
                                continue;
                            }

                            AnswerObject answerObject = answers.get(questionCode);

                            WebElement answerElement = Util.findByClassName(contentElement, "answer");
                            if (null != answerElement) {
                                // 开始答题
                                Util.doExercise(driver, answerElement, answerObject.getQuestionType(), answerObject.getAnswers());
                            } else {
                                // 如果为空就是填空题 是没有答案对比的
                                // 10-23 加了一个文件上传
                                Util.doExercise(driver, singleSubject, answerObject.getQuestionType(), answerObject.getAnswers());
                            }
                            //休眠一秒
                            TimeUnit.SECONDS.sleep(1);
                            //  FIXME 此时答案是没有保存的，要点击结束试答题
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        Thread.sleep(2000);
                        // FIX ME 获取当前页面的下一页信息 设置为while还是有下一页就继续循环
                        WebElement nextPage = Util.findNextPage(driver);
                        if (nextPage != null) {
                            nextPage.click();
                        } else {
                            hashNextPage = false;
                            // FIXME  此时答案是没有保存的，要点击结束试答题 当没有下一页的时候，可以选择提交
                        }
                    }
                }


                Thread.sleep(2000);

                //回到试题首页 (保存最后一题答案)
           /* WebElement element2 = driver.findElement(By.id("quiznavbutton1"));
            element2.click();*/

                WebElement submitbtns = driver.findElement(By.className("submitbtns"));
                WebElement next = submitbtns.findElement(By.cssSelector("input[name='next']"));
                next.click();
                Thread.sleep(2000);

                if (!commit) {
                    log.info("答案不提交");
                    TimeUnit.SECONDS.sleep(2);
                    continue;
                }

                //提交答案
                List<WebElement> saveButtons = driver.findElements(By.cssSelector("button[type='submit']"));
                //System.out.println("提交");
                //System.out.println(saveButtons.size());
                if (!CollectionUtils.isEmpty(saveButtons)) {
                    for (WebElement webElement : saveButtons) {
                        String text = webElement.getText();
                        if (text.contains("提交")) {
                            webElement.click();
                        }
                    }
                }

                TimeUnit.SECONDS.sleep(3);
                //全部提交
                //提交答案


                List<WebElement> confirmation = driver.findElements(By.className("confirmation-dialogue"));
                if (!CollectionUtils.isEmpty(confirmation)) {
                    for (WebElement webElement : confirmation) {
                        List<WebElement> submitElement = webElement.findElements(By.tagName("input"));
                        if (!CollectionUtils.isEmpty(submitElement)) {
                            for (WebElement element1 : submitElement) {
                                String value = element1.getAttribute("value");
                                if (value.contains("提交")) {
                                    //点击确认后页面会刷新,此时为了防止丢到元素抛异常，这里直接获取第一个，不再循环
                                    element1.click();
                                    break;
                                }

                            }
                        }
                    }
                }


                List<WebElement> submitButtons = driver.findElements(By.tagName("input"));
                if (!CollectionUtils.isEmpty(submitButtons)) {
                    for (WebElement webElement : submitButtons) {
                        String text = webElement.getText();
                        if (text.contains("提交")) {
                            webElement.click();
                        }
                    }
                }

                TimeUnit.SECONDS.sleep(2);

                try {
                    //判断是否符合要求
                    Map<String, String> scoreMap = new HashMap<>();
                    WebElement tbody = driver.findElement(By.tagName("tbody"));
                    List<WebElement> trs = tbody.findElements(By.tagName("tr"));
                    for (WebElement tr : trs) {
                        //th
                        WebElement th = tr.findElement(By.tagName("th"));
                        //td
                        WebElement td = tr.findElement(By.tagName("td"));
                        scoreMap.put(th.getText().trim(), td.getText().trim());
                    }
                    String score = scoreMap.get("分数");
                    String[] strs = score.split("/");
                    float s = Float.valueOf(strs[0]) / Float.valueOf(strs[1]);
                    if (s < 0.80) {
                        scoreMap.put("科目", subjectName);
                        scoreMap.put("用户名", userName);
                        scoreMap.put("密码", password);
                        scoreMap.put("形考链接", urlTask);

                        if (push) {
                            HttpClientUtil.send(scoreMap);
                        }

                        System.out.println("答题不及格");
                        System.out.println(scoreMap.toString());
                    }
                } catch (Exception e) {

                }

            }
            Thread.sleep(5000);
            driver.close();
            driver.quit();
        }

        if (Constant.USER_QUEUE.size() == 0) {
            log.info("所有用户均已执行完毕，系统将在10min后结束");
            TimeUnit.MINUTES.sleep(10);
            return;
        }
    }

}
